import mqtt from "mqtt";
import { ref } from 'vue';

export class MQTTManager {
  private client: mqtt.MqttClient | null = null;
  private subscriptions: Map<string, Set<(message: any) => void>> = new Map();
  private connecting = false;
  
  // 响应式状态
  public connected = ref(false);
  public error = ref<Error | null>(null);
  public lastMessage = ref<{topic: string, payload: any} | null>(null);
  public enabled = ref(false);

  // 启用 MQTT 功能
  enable(options: mqtt.IClientOptions & { url: string }) {
    this.enabled.value = true;
    return this.connect(options);
  }

  // 禁用 MQTT 功能
  disable() {
    this.enabled.value = false;
    this.disconnect();
  }

  // 连接 MQTT 服务器
  async connect(options: mqtt.IClientOptions & { url: string }) {
    if (!this.enabled.value) {
      console.warn('MQTT is disabled');
      return;
    }

    if (this.connecting) return;
    this.connecting = true;
    this.error.value = null;

    try {
      const { url, ...mqttOptions } = options;
      this.client = mqtt.connect(url, {
        ...mqttOptions,
        reconnectPeriod: 5000,
        keepalive: 60,
        clean: true
      });

      this.setupEventHandlers();
    } catch (err) {
      this.error.value = err as Error;
      this.connecting = false;
      console.error('MQTT Connection failed:', err);
    }
  }

  private setupEventHandlers() {
    if (!this.client) return;

    this.client.on('connect', () => {
      console.log('MQTT Connected');
      this.connected.value = true;
      this.connecting = false;
      this.error.value = null;
      this.resubscribe();
    });

    this.client.on('message', (topic, message) => {
      const callbacks = this.subscriptions.get(topic);
      if (callbacks) {
        const payload = message.toString();
        try {
          const jsonData = JSON.parse(payload);
          this.lastMessage.value = { topic, payload: jsonData };
          callbacks.forEach(callback => callback(jsonData));
        } catch {
          this.lastMessage.value = { topic, payload };
          callbacks.forEach(callback => callback(payload));
        }
      }
    });

    this.client.on('error', (error) => {
      console.error('MQTT Error:', error);
      this.error.value = error;
      this.connecting = false;
      this.connected.value = false;
    });

    this.client.on('close', () => {
      console.log('MQTT Connection closed');
      this.connected.value = false;
      this.connecting = false;
    });
  }

  subscribe(topic: string, callback: (message: any) => void) {
    if (!this.enabled.value) {
      console.warn('MQTT is disabled');
      return;
    }

    if (!this.client?.connected) {
      console.warn('MQTT not connected, will subscribe when connected');
    }

    if (!this.subscriptions.has(topic)) {
      this.subscriptions.set(topic, new Set());
      if (this.client?.connected) {
        this.client.subscribe(topic);
      }
    }
    this.subscriptions.get(topic)?.add(callback);
  }

  unsubscribe(topic: string, callback: (message: any) => void) {
    const callbacks = this.subscriptions.get(topic);
    if (callbacks) {
      callbacks.delete(callback);
      if (callbacks.size === 0) {
        this.subscriptions.delete(topic);
        if (this.client?.connected) {
          this.client.unsubscribe(topic);
        }
      }
    }
  }

  private resubscribe() {
    if (!this.client?.connected) return;
    
    for (const topic of this.subscriptions.keys()) {
      this.client.subscribe(topic);
    }
  }

  publish(topic: string, message: any) {
    if (!this.enabled.value) {
      console.warn('MQTT is disabled');
      return;
    }

    if (!this.client?.connected) {
      console.error('MQTT not connected');
      return;
    }

    const payload = typeof message === 'string' ? message : JSON.stringify(message);
    this.client.publish(topic, payload);
  }

  disconnect() {
    if (this.client) {
      this.client.end();
      this.client = null;
    }
    this.connected.value = false;
    this.error.value = null;
    this.lastMessage.value = null;
    this.subscriptions.clear();
  }
}

// 创建单例实例
export const mqttManager = new MQTTManager(); 